package com.skyworth.web.shiro;

import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSubjectFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {

  private static Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();

  @Bean(name = "ShiroRealmImpl")
  public ShiroRealmImpl getShiroRealm() {
    return new ShiroRealmImpl();
  }

  @Bean(name = "lifecycleBeanPostProcessor")
  public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }

  @Bean
  public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
    daap.setProxyTargetClass(true);
    return daap;
  }

  @Bean(name = "securityManager")
  public DefaultWebSecurityManager getDefaultWebSecurityManager() {
    DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
    dwsm.setSubjectFactory(getDefaultWebSubjectFactory());
    dwsm.setRealm(getShiroRealm());
    return dwsm;
  }

  @Bean(name = "subjectFactory")
  public DefaultWebSubjectFactory getDefaultWebSubjectFactory() {
    return new ShiroWebSubjectFactory();
  }

  @Bean
  public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
    AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
    aasa.setSecurityManager(getDefaultWebSecurityManager());
    return new AuthorizationAttributeSourceAdvisor();
  }

  @Bean(name = "shiroFilter")
  public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());
    shiroFilterFactoryBean.setLoginUrl("/login");
    filterChainDefinitionMap.put("/", "authc");
    filterChainDefinitionMap.put("/map", "anon");
    filterChainDefinitionMap.put("/maps", "anon");
    filterChainDefinitionMap.put("/upload", "anon");
    filterChainDefinitionMap.put("/uploadfiles/**", "anon");

    //wechat
    filterChainDefinitionMap.put("/wechat/**", "anon");

    // Api
    filterChainDefinitionMap.put("/api/**", "anon");
    filterChainDefinitionMap.put("/waiter/**", "anon");

    filterChainDefinitionMap.put("/reg", "anon");
    filterChainDefinitionMap.put("/user/register", "anon");
    filterChainDefinitionMap.put("/login", "anon");
    filterChainDefinitionMap.put("/attachments/**", "anon");
    filterChainDefinitionMap.put("/validatecode", "anon");
    filterChainDefinitionMap.put("/error/**", "anon");
    filterChainDefinitionMap.put("/templates/**", "anon");
    filterChainDefinitionMap.put("/css/**", "anon");
    filterChainDefinitionMap.put("/img/**", "anon");
    filterChainDefinitionMap.put("/js/**", "anon");
    filterChainDefinitionMap.put("/fonts/**", "anon");
    filterChainDefinitionMap.put("/common/**", "anon");
    filterChainDefinitionMap.put("/waiter/index", "anon");

    filterChainDefinitionMap.put("/admin/**", "authc");
    filterChainDefinitionMap.put("/cashier/**", "authc");
    filterChainDefinitionMap.put("/waiterOrder/**", "authc");

    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    return shiroFilterFactoryBean;
  }
}